package com.urbanski.clipboard.server.action.message;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import com.urbanski.clipboard.common.message.CreateMessage;
import com.urbanski.clipboard.common.message.DisconnectMessage;
import com.urbanski.clipboard.common.message.JoinMessage;
import com.urbanski.clipboard.common.message.LeaveMessage;
import com.urbanski.clipboard.common.message.Message;
import com.urbanski.clipboard.common.message.PauseMessage;
import com.urbanski.clipboard.common.message.TestMessage;
import com.urbanski.clipboard.common.message.UnpauseMessage;
import com.urbanski.clipboard.server.ClientSocket;

public abstract class ServerMessageHandler
{
	protected ClientSocket client;

	private static Map<Class<? extends Message>, Class<? extends ServerMessageHandler>> handlerMap = new HashMap<>();

	static
	{
		handlerMap.put(TestMessage.class, TestMessageHandler.class);
		handlerMap.put(DisconnectMessage.class, DisconnectMessageHandler.class);
		handlerMap.put(CreateMessage.class, CreateMessageHandler.class);
		handlerMap.put(JoinMessage.class, JoinMessageHandler.class);
		handlerMap.put(LeaveMessage.class, LeaveMessageHandler.class);
		handlerMap.put(PauseMessage.class, PauseMessageHandler.class);
		handlerMap.put(UnpauseMessage.class, UnpauseMessageHandler.class);
	}

	public ServerMessageHandler(ClientSocket client)
	{
		this.client = client;
	}

	public abstract void handle(Message message);

	public static ServerMessageHandler getHandler(ClientSocket client, Message message) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException
	{
		Class<? extends ServerMessageHandler> handlerClass = handlerMap.get(message.getClass());
		ServerMessageHandler handler;
		Constructor<? extends ServerMessageHandler> constructor = handlerClass.getConstructor(ClientSocket.class);
		handler = constructor.newInstance(client);
		return handler;
	}
}
